﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Zove.Scripting.Core;
using EmbeddedSharp.Scripting;
using EmbeddedSharp.Studio;
using System.Configuration;
using DigitalRune.Windows.TextEditor.Actions;

namespace Zove.Scripting.Editor {
    public partial class ScriptingEditorView : Form {

        private IContext context;

        public const string TITLE = "Embedded# Studio";

        public ScriptingEditorView() {
            InitializeComponent();

            this.Load += new EventHandler(ScriptingEditorView_Load);
            this.DragEnter += new DragEventHandler(ScriptingEditorView_DragEnter);
            this.DragDrop += new DragEventHandler(ScriptingEditorView_DragDrop);
            this.FormClosing += new FormClosingEventHandler(ScriptingEditorView_FormClosing);
        }

        public ScriptingEditorView(IContext context)
            : this() {
            this.context = context;
        }

        public ScriptingEditorView(string fileName)
            : this() {
            UpdateView(fileName);
        }

        public ScriptingEditorView(string fileName, IContext context)
            : this(fileName) {
            this.context = context;
        }

        public void UpdateView(string fileName) {
            if (string.IsNullOrEmpty(fileName) || !System.IO.File.Exists(fileName)) {
                this.fileName = string.Empty;
                this.tbSource.Text = string.Empty;
                this.Text = TITLE + " - [Untitled]";

                return;
            }

            this.fileName = fileName;
            string source = System.IO.File.ReadAllText(fileName);
            this.tbSource.Text = source;
            this.Text = TITLE + " - [" + this.fileName + "]";
        }

        public void ScriptingEditorView_DragEnter(object sender, DragEventArgs e) {
            if (e.Data.GetDataPresent(DataFormats.FileDrop, false) == true) {
                e.Effect = DragDropEffects.All;
            }
        }

        public void ScriptingEditorView_DragDrop(object sender, DragEventArgs e) {
            string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
            this.fileName = files[0];

            UpdateView(fileName);
        }

        public void ScriptingEditorView_Load(object sender, EventArgs e) {
            this.cmdStop.Enabled = false;

            string name = ConfigurationManager.AppSettings["font"];
            int size = Convert.ToInt32(
                ConfigurationManager.AppSettings["font size"]);

            this.tbSource.Font = new Font(name, size);
        }

        public void ScriptingEditorView_FormClosing(object sender, EventArgs e) {

        }

        private void eitToolStripMenuItem_Click(object sender, EventArgs e) {
            this.Close();
        }

        private void openToolStripMenuItem_Click(object sender, EventArgs e) {
            UpdateView(string.Empty);
        }

        private void openToolStripMenuItem1_Click(object sender, EventArgs e) {
            OpenFileDialog d = new OpenFileDialog();

            d.Filter = "All ZoveScript File Types | *.zs";
            if (d.ShowDialog() == DialogResult.OK) {
                UpdateView(d.FileName);
            }
        }

        private string fileName = string.Empty;

        private void saveToolStripMenuItem_Click(object sender, EventArgs e) {
            if (string.IsNullOrEmpty(fileName)) {
                saveAsToolStripMenuItem_Click(sender, e);
            } else {
                System.IO.File.WriteAllText(fileName, this.tbSource.Text);
            }
        }

        private void saveAsToolStripMenuItem_Click(object sender, EventArgs e) {
            SaveFileDialog d = new SaveFileDialog();

            d.Filter = "All ZoveScript File Types | *.zs";
            if (d.ShowDialog() == DialogResult.OK) {
                System.IO.File.WriteAllText(d.FileName, this.tbSource.Text);
                UpdateView(d.FileName);
            }

        }
        private ZoveScriptingObject script = null;

        private void cmdRun_Click_1(object sender, EventArgs e) {
            this.toolStripStatusLabel1.Text = "Evaluating ...";

            TextBoxWriter writer = new TextBoxWriter(this.tbOutput);
            Console.SetOut(writer);

            if (this.context == null) {
                script = new ZoveScriptingObject(this.tbSource.Text);
            } else {
                script = new ZoveScriptingObject(this.tbSource.Text, this.context);
            }
            this.cmdStop.Enabled = true;

            script.RunAsync();

            this.toolStripStatusLabel1.Text = "Ready";
        }

        private void cmdStop_Click(object sender, EventArgs e) {
            if (script == null) {
                return;
            }

            script.Abort();

            this.cmdStop.Enabled = false;
        }

        private void btnClear_Click_1(object sender, EventArgs e) {

        }

        private void runToolStripMenuItem_Click(object sender, EventArgs e) {
            cmdRun_Click_1(sender, e);
        }

        private void cmdClearOutput_Click(object sender, EventArgs e) {
            this.tbOutput.Text = string.Empty;
        }

        private void cmdOptions_Click(object sender, EventArgs e) {
            OptionsView view = new OptionsView();

            if (view.ShowDialog() == DialogResult.OK) {
            }
        }

        private void optionsToolStripMenuItem_Click(object sender, EventArgs e) {
            cmdOptions_Click(sender, e);
        }

        private void clearOutputToolStripMenuItem_Click(object sender, EventArgs e) {
            cmdClearOutput_Click(sender, e);
        }

        private void undoToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Undo undo = new Undo();
            undo.Execute(this.tbSource.ActiveTextAreaControl.TextArea);
        }

        private void redoToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Redo redo = new Redo();
            Execute(redo);
        }

        public void Execute(AbstractEditAction action)
        {
            action.Execute(this.tbSource.ActiveTextAreaControl.TextArea);
        }

        private void cutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Cut cut = new Cut();
            Execute(cut);
        }

        private void copyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Execute(new Copy());
        }

        private void pasteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Execute(new Paste());
        }

        private void deleteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Execute(new Delete());
        }
    }
}
